using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GameFramework

{
    public  class FrameModule
    {
        #region Fields

        // hinh cua frame
        private Texture2D _sourceTexture;
        public Texture2D SourceTexture
        {
            get
            {
                return _sourceTexture;
            }
            set
            {
                _sourceTexture = value;
            }
        }


        // ID de chay animation
        private int _id;
        public int ID
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
        }

        // ten
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }


        // frame dan ve
        private int _numOfModuleFrame;
        public int NumOfModuleFrame
        {
            get
            {
                return _numOfModuleFrame;
            }
            set
            {
                _numOfModuleFrame = value;
            }
        }


        private SpriteBatch _spriteBatch;
        public SpriteBatch SpriteBatch
        {
            get
            {
                return _spriteBatch;
            }
            set
            {
                _spriteBatch = value;
            }
        }


        private List<Rectangle> _sourceRectangle;
        public List<Rectangle> SourceRectangle
        {
            get
            {
                return _sourceRectangle;
            }
            set
            {
                _sourceRectangle = value;
            }
        }

        public Rectangle Bound
        {
            get
            {
                Rectangle rect = _sourceRectangle[0];
                if (_sourceRectangle.Count > 1)                
                {
                    rect = _sourceRectangle[0];
                    for (int i = 1; i < _sourceRectangle.Count; i++)
                    {
                        Rectangle sourRect = _sourceRectangle[i];
                        Rectangle.Union(ref rect, ref sourRect, out rect);
                    }                    
                }

                if (_scale <= 1)
                {
                    float scaleX = (1 - _scale) * rect.Width;
                    float scaleY = (1 - _scale) * rect.Height;
                    return new Rectangle((int)(_position.X - rect.Width / 2 + scaleX / 2), (int)(_position.Y - rect.Height / 2 + scaleY / 2), (int)(rect.Width - scaleX), (int)(rect.Height - scaleY));
                }
                else
                {
                    float scaleX = (_scale - 1) * rect.Width;
                    float scaleY = (_scale - 1) * rect.Height;
                    return new Rectangle((int)(_position.X - rect.Width / 2 - scaleX / 2), (int)(_position.Y - rect.Height / 2 - scaleY / 2), (int)(rect.Width + scaleX), (int)(rect.Height +scaleY));
                }
            }
        }

        private Vector2 _position;
        public Vector2 Position
        {
            get
            {
                return _position;
            }
            set
            {
                _position = value;
            }
        }


        private List<Vector2> _offsets;
        public List<Vector2> Offsets
        {
            get
            {
                return _offsets;
            }
            set
            {
                _offsets = value;
            }
        }

        private List<Vector2> _origin;
        public List<Vector2> Origin
        {
            get
            {
                return _origin;
            }
            set
            {
                _origin = value;
            }
        }


        private Color _color;
        public Color Color
        {
            get
            {
                return _color;
            }
            set
            {
                _color = value;
            }
        }


        private byte _opacity;
        public byte Opacity
        {
            get
            {
                return _opacity;
            }
            set
            {
                _opacity = value;
                _color = new Color(_opacity, _opacity, _opacity, _opacity);
            }
        }

        private float _scale;
        public float Scale
        {
            get
            {
                return _scale;
            }
            set
            {
                _scale = value;
            }
        }


        private float _rotate;
        public float Rotate
        {
            get
            {
                return _rotate;
            }
            set
            {
                _rotate = value;
            }
        }


 
        private SpriteEffects _spriteEffects;
        public SpriteEffects SpriteEffects
        {
            get
            {
                return _spriteEffects;
            }
            set
            {
                _spriteEffects = value;
            }
        }

        public float Diagonal
        {
            get
            {
                float x = Bound.Width;
                float y = Bound.Height;
                return (float)Math.Sqrt(x * x + y * y);
            }
        }



        #endregion

        #region Constructor

        public FrameModule()
        {
            _sourceTexture = null;
            _color = Color.White;
            _opacity = 255;
            _origin = new List<Vector2>();
            _offsets = new List<Vector2>();
            _sourceRectangle = new List<Rectangle>();            
            _position = new Vector2(float.MinValue, float.MinValue);
            _rotate = 0;
            _numOfModuleFrame = 0;
            _scale = 1;            
            _spriteEffects = Microsoft.Xna.Framework.Graphics.SpriteEffects.None;
        }

        public FrameModule(Texture2D texture)
        {
            _sourceTexture = texture;
            _color = Color.White;
            _opacity = 255;
            _offsets = new List<Vector2>();
            _origin = new List<Vector2>();
            _sourceRectangle = new List<Rectangle>();
            _position = new Vector2(float.MinValue, float.MinValue);
            _rotate = 0;
            _scale = 1;
            _spriteEffects = Microsoft.Xna.Framework.Graphics.SpriteEffects.None;
        }      
        #endregion

        #region Methods
        

        public void Add(Rectangle frameRect, Vector2 offset)
        {           
            _sourceRectangle.Add(frameRect);
            _offsets.Add(offset);
            _origin.Add(new Vector2(frameRect.Width/2,frameRect.Height/2));
        }


        public void Draw()
        {
            _spriteBatch.Begin();
            for(int i = 0;i<_numOfModuleFrame;i++)
            {
                _spriteBatch.Draw(_sourceTexture,
                    _position + _offsets[i],
                    _sourceRectangle[i], 
                    _color, 
                    _rotate,
                    _origin[i],
                    _scale, 
                    _spriteEffects,
                    0);
            }
            _spriteBatch.End();
        }


        public void Draw(Vector2 position)
        {
            _spriteBatch.Begin();
            for (int i = 0; i < _numOfModuleFrame; i++)
            {
                _spriteBatch.Draw(_sourceTexture, 
                    position + _offsets[i], 
                    _sourceRectangle[i],
                    _color, 
                    _rotate, 
                    _origin[i],
                    _scale, 
                    _spriteEffects,
                    0);
            }
            _spriteBatch.End();
        }

        public void Draw(Vector2 position,Vector2 origin)
        {
            _spriteBatch.Begin();
            for (int i = 0; i < _numOfModuleFrame; i++)
            {
                _spriteBatch.Draw(_sourceTexture, position + _offsets[i],
                    _sourceRectangle[i],
                    _color, 
                    _rotate,
                    origin,
                    _scale, 
                    _spriteEffects,
                    0);
            }
            _spriteBatch.End();
        }

        public void Draw(Vector2 position, float scale, float rotate)
        {
            _spriteBatch.Begin();
            for (int i = 0; i < _numOfModuleFrame; i++)
            {
                _spriteBatch.Draw(_sourceTexture, 
                    position + _offsets[i],
                    null, 
                    _color,
                    rotate,
                    _origin[i],
                    scale,
                    _spriteEffects,
                    0);
            }
            _spriteBatch.End();
        }

        public void Draw(Vector2 position, float scale, float rotate, Color color)
        {
            _spriteBatch.Begin();
            for (int i = 0; i < _numOfModuleFrame; i++)
            {
                _spriteBatch.Draw(_sourceTexture,
                    position + _offsets[i],
                    _sourceRectangle[i],
                    color,
                    rotate,
                    _origin[i],
                    scale,
                    _spriteEffects,
                    0);
            }
            _spriteBatch.End();
        }

        public void Draw(Rectangle desRect, Rectangle sourceRect)
        {
            _spriteBatch.Begin();
            _spriteBatch.Draw(_sourceTexture, desRect, sourceRect, Color.White);
            _spriteBatch.End();
        }
        #endregion
    }
}
